package com.lj.file.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lj.common_web.annotation.ResponseResultVo;
import com.lj.common_web.utils.ServletUtil;
import com.lj.file.param.FileDetailPageParam;
import com.lj.file.param.InitChunkUploadParam;
import com.lj.file.param.UploadParam;
import com.lj.file.result.FileDetailInfoResult;
import com.lj.file.result.FileDetailPageResult;
import com.lj.file.result.PlatformInfoResult;
import com.lj.file.service.FileDetailService;
import com.lj.file.service.FileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.dromara.x.file.storage.core.upload.FilePartInfo;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 文件记录表 前端控制器
 * </p>
 *
 * @author lj
 * @since 2025-06-26 16:30:45
 */
@RestController
@RequestMapping("/file")
@ResponseResultVo
@Tag(name = "文件管理")
@Slf4j
public class FileController {

    @Resource
    private FileDetailService fileDetailService;

    @Resource
    private FileService fileService;

    @GetMapping("/page")
    @SaCheckPermission("file:file_detail:list")
    @Operation(summary = "文件记录表 分页查询")
    public IPage<FileDetailPageResult> page(@ParameterObject FileDetailPageParam param) {
        return fileDetailService.page(param);
    }

    @GetMapping("/platformInfo")
    @SaCheckPermission("file:file_detail:list")
    @Operation(summary = "获取平台信息")
    public List<PlatformInfoResult> platformInfo() {
        return fileService.platformInfo();
    }

    @GetMapping("/info/{id}")
    @SaCheckPermission("file:file_detail:info")
    @Operation(summary = "文件记录表 信息")
    public FileDetailInfoResult info(@PathVariable("id") @Parameter(name = "id", description = "文件记录表 id") Long id) {
        if (id == null) {
            return null;
        }
        return fileDetailService.info(id);
    }

    @PostMapping("/upload")
    @SaCheckPermission("file:file_detail:upload")
    @Operation(summary = "上传文件")
    public List<FileDetailInfoResult> upload(@RequestPart(value = "files", required = false) MultipartFile[] files, String platform) {
        if (ArrayUtil.isEmpty(files)) {
            return Collections.emptyList();
        }
        List<FileDetailInfoResult> result = new ArrayList<>();
        for (MultipartFile file : files) {
            UploadParam param = new UploadParam();
            try {
                param.setPlatform(platform);
                param.setInputStream(file.getInputStream());
                param.setOriginalName(file.getOriginalFilename());
                result.add(fileService.upload(param));
            } catch (Exception e) {
                // 防止批量上传的时候，某个文件上传失败影响其他文件的上传
                log.warn("文件({})上传失败!", param.getOriginalName(), e);
            }
        }
        return result;
    }

    @PostMapping("/chunk/init")
    @SaCheckPermission("file:file_detail:upload")
    @Operation(summary = "初始化分片上传")
    public FileDetailInfoResult initChunkUpload(@RequestBody @Validated InitChunkUploadParam param) {
        return fileService.initChunkUpload(param);
    }

    @PostMapping("/chunk/upload")
    @SaCheckPermission("file:file_detail:upload")
    @Operation(summary = "分片上传")
    public FilePartInfo chunkUpload(MultipartFile partFile, int chunkNumber, Long fileId) throws IOException {
        return fileService.chunkUpload(partFile.getInputStream(), chunkNumber, fileId);
    }

    @PostMapping("/chunk/abort")
    @SaCheckPermission("file:file_detail:upload")
    @Operation(summary = "取消分片上传")
    public void chunkAbort(Long fileId) {
        fileService.chunkAbort(fileId);
    }


    @GetMapping("/download/{id}")
    @SaCheckPermission("file:file_detail:download")
    @Operation(summary = "下载文件")
    public void download(@PathVariable("id") Long id) throws IOException {
        FileDetailInfoResult result = fileDetailService.info(id);
        ServletUtil.download(result.getOriginalFilename(),
                outputStream -> fileService.download(id, outputStream));
    }

    @PostMapping("/delete")
    @SaCheckPermission("file:file_detail:delete")
    @Operation(summary = "文件记录表 删除")
    public void delete(@RequestBody List<Long> ids) {
        fileService.delete(ids);
    }

    @GetMapping("/export/excel")
    @SaCheckPermission("file:file_detail:export")
    @Operation(summary = "文件记录表 excel导出")
    public void exportExcel(@ParameterObject FileDetailPageParam param) throws IOException {
        ServletUtil.download("文件记录表-导出数据.xlsx",
                outputStream -> fileDetailService.exportExcel(param, outputStream));
    }


}

